home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / game / alien / alien.c next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  34.2 KB  |  1,190 lines

  1. /* アトミックエイリアン 1994年6月8日-8月2日 */
  2. /* 1994年6月11日-7月20日 マシン故障  再開 7月26日
  3.    α版完成 8月1日 β版完成 8月2日 */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9.  
  10. #define R 32   /* 赤 */
  11. #define G 1024 /* 緑 */
  12. #define B 1    /* 青 */
  13.  
  14.  
  15. #define X 0   /* 画面左上のX座標 */
  16. #define Y 8   /* 画面左上のY座標 */
  17.  
  18.  
  19. char CHRFILE[]="grp.pat";  /* キャラクタパターンファイル名 */
  20. char SPRITE[]="spr.pat";   /* スプライトパターンファイル名 */
  21.  
  22. char gwork[1536];        /* グラフイックBIOSワーク */
  23.  
  24. short work[13][256];   /* 背景のキャラクタパターンワーク */
  25. short chr[9][64];      /* 背景のキャラクタパターン */
  26. short num[10][256];    /* アナログ数字のキャラクタパターン */
  27.  
  28. #define WALL 6 /* 障害物のマップコードの最大値 */
  29.  
  30. int MAP[30][30];         /* マップ   0:壁左上
  31.                                      1:壁右上
  32.                                      2:壁左下
  33.                                      3:壁右下
  34.                                      4:壁上辺
  35.                                      5:壁下辺
  36.                                      6:枠
  37.                                      7:dot
  38.                                      8:空白 */
  39.  
  40. int end;       /* ゲーム終了フラグ 0:続行 1:ゲーム終了 */
  41. int game_over; /* ゲームオーバーフラグ 0:続行 1:ゲームオーバー */
  42.  
  43. int hi_score,score;
  44.  
  45. #define SPK 6 /* 人のスピード */
  46. int spk;      /* 人のスピードワーク */
  47. int kx,ky; /* 人の座標 */
  48. int kh;    /* 人の向き  0:上 1:下 2:左 3:右 */
  49. int life;  /* 人の残り */
  50. int gain;  /* 人追加フラグ 0:未追加 1:追加済 */
  51. int dot;   /* ドットの残り数 */
  52.  
  53. #define SPB 1 /* 矢のスピード */
  54. int spb;      /* 矢のスピードワーク */
  55. int bx,by; /* 矢の座標 */
  56. int bh;    /* 矢の向き  0:上 1:下 2:左 3:右 */
  57. int bj;    /* 矢の状態  0:発射可能 1:飛行中 2:発射準備 */
  58.  
  59. #define LIMIT 3100 /* ボスエイリアンが仮死状態でいる時間(定数) */
  60. int limit; /* ボスエイリアンが蘇るまでのリミットタイム */
  61. int max_alien; /* エイリアンの最大数 */
  62. int left_alien; /* エイリアンの残り数 */
  63. int clear; /* ステージクリアフラグ */
  64.  
  65. #define SPA00 7   /* ボスエイリアンのスピード(平常時) */
  66. #define SPA01 6   /* ボスエイリアンのスピード(残り1匹時) */
  67. #define SPA10 9   /* ザコエイリアンのスピード(ドット残りあり) */
  68. #define SPA11 7   /* ザコエイリアンのスピード(ドット残りなし) */
  69. int SPA[8];      /* エイリアンのスピード */
  70. int spa[8];      /* エイリアンのスピードワーク */
  71. int ax[8],ay[8]; /* エイリアンの座標 */
  72. int ah[8];    /* エイリアンの向き  0:上 1:下 2:左 3:右 */
  73. int aj[8];    /* エイリアンの状態  0:死亡 1:生存 */
  74. int aj[8];    /* エイリアンの状態  0:死亡 1:生存 */
  75. int dumm_boss; /* ボスエイリアンのダメージ */
  76.  
  77. /* サウンド変数 */
  78. int spoint[6];                     /* サウンドデータポインタ */
  79. int sinit[28];                     /* サウンドデータ先頭ポインタ */
  80. int skunt[6];                      /* カウンタ */
  81. int feed[6]={1,1,7,1,1,1};         /* 各チャンネルの音質 */
  82. /* チャンネル 0 : エイリアンワープ音,人死亡音,
  83.                   ボス仮死音,ボスダメージ音,ボス死亡音,ザコ死亡音
  84.               1 : ドット喰い音,リミット減少音
  85.               2 : アロー発射音
  86.               3 : 仮死ボス命中音
  87.               4 : 人追加音
  88.               5 : ボス目覚め音
  89. */
  90.  
  91. #define T0  7              /* ドット喰い音のテンポ */
  92. #define T1  70             /* エイリアンワープ音のテンポ */
  93. #define T2  70             /* 人死亡音のテンポ */
  94. #define T3  70             /* ボス仮死音のテンポ */
  95. #define T4  70             /* ボスダメージ音のテンポ */
  96. #define T5  70             /* ボス死亡音のテンポ */
  97. #define T6  70             /* ザコ死亡音のテンポ */
  98. #define T7  7              /* アロー発射音のテンポ */
  99. #define T8  50             /* 仮死ボス命中音のテンポ */
  100. #define T9  70             /* 人追加音のテンポ */
  101. #define T10 27             /* ボス目覚め音のテンポ */
  102. #define T11 10             /* リミット減少音のテンポ */
  103.  
  104. int sdata[]={                      /* サウンドデータ OCT,TONE,VOL,LONG */
  105.                             /* 音階 0  1  2  3  4  5  6  7  8  9  10 11 12
  106.                                     休 C  C# D  D# E  F  F# G  G# A  A# B */
  107.              -1,            /* No0 ドット喰い音 */
  108.              5, 1,13,T0,
  109.              5, 1,15,T0,
  110.              5, 1,17,T0,
  111.              1, 0,128,0,
  112.  
  113.              -1,            /* No1 エイリアンワープ音 */
  114.              5,1 ,11,T1,
  115.              5,2 ,13,T1,
  116.              5,1 ,15,T1,
  117.              5,2 ,17,T1,
  118.              5,1 ,19,T1,
  119.              5,2 ,21,T1,
  120.              5,1 ,23,T1,
  121.              5,2 ,25,T1,
  122.              1, 0,128,0,
  123.  
  124.              -1,            /* No2 人死亡音 */
  125.              5,10,11,T2,
  126.              5, 6,11,T2,
  127.              5, 3,11,T2,
  128.              5,10,11,T2,
  129.              5, 6,11,T2,
  130.              5, 3,11,T2,
  131.              5,10,11,T2,
  132.              5, 6,11,T2,
  133.              5, 3,11,T2,
  134.              5,10,11,T2,
  135.              5, 6,11,T2,
  136.              5, 3,11,T2,
  137.              5,10,11,T2,
  138.              5, 6,11,T2,
  139.              5, 3,11,T2,
  140.              5,10,11,T2,
  141.              5, 6,11,T2,
  142.              5, 3,11,T2,
  143.              1, 0,128,0,
  144.  
  145.              -1,            /* No3 ボス仮死音 */
  146.              5, 8,11,T3,
  147.              5, 1,11,T3,
  148.              5,10,11,T3,
  149.              5, 2,11,T3,
  150.              5, 8,11,T3,
  151.              5, 1,11,T3,
  152.              5,10,11,T3,
  153.              5, 2,11,T3,
  154.              5, 8,11,T3,
  155.              5, 1,11,T3,
  156.              5,10,11,T3,
  157.              5, 2,11,T3,
  158.              5, 8,11,T3,
  159.              5, 1,11,T3,
  160.              5,10,11,T3,
  161.              5, 2,11,T3,
  162.              1, 0,128,0,
  163.  
  164.              -1,            /* No4 ボスダメージ音 */
  165.              4,12,11,T4,
  166.              5, 3,11,T4,
  167.              5, 8,11,T4,
  168.              4,12,11,T4,
  169.              5, 3,11,T4,
  170.              5, 8,11,T4,
  171.              4,12,11,T4,
  172.              5, 3,11,T4,
  173.              5, 8,11,T4,
  174.              4,12,11,T4,
  175.              5, 3,11,T4,
  176.              5, 8,11,T4,
  177.              1, 0,128,0,
  178.  
  179.              -1,            /* No5 ボス死亡音 */
  180.              5, 5,11,T5,
  181.              5, 3,11,T5,
  182.              5, 8,11,T5,
  183.              5, 6,11,T5,
  184.              5, 5,11,T5,
  185.              5, 3,11,T5,
  186.              5, 8,11,T5,
  187.              5, 6,11,T5,
  188.              5, 5,11,T5,
  189.              5, 3,11,T5,
  190.              5, 8,11,T5,
  191.              5, 6,11,T5,
  192.              1, 0,128,0,
  193.  
  194.              -1,            /* No6 ザコ死亡音 */
  195.              5, 3,11,T6,
  196.              5, 6,11,T6,
  197.              5, 8,11,T6,
  198.              5, 6,11,T6,
  199.              5, 3,11,T6,
  200.              5, 6,11,T6,
  201.              5, 8,11,T6,
  202.              5, 6,11,T6,
  203.              5, 3,11,T6,
  204.              5, 6,11,T6,
  205.              5, 8,11,T6,
  206.              5, 6,11,T6,
  207.              5, 3,11,T6,
  208.              5, 6,11,T6,
  209.              5, 8,11,T6,
  210.              5, 6,11,T6,
  211.              1, 0,128,0,
  212.  
  213.              -1,            /* No7 アロー発射音 */
  214.              6,12,15,T7,
  215.              6,11,15,T7,
  216.              6,10,15,T7,
  217.              6, 9,15,T7,
  218.              6, 8,15,T7,
  219.              6, 7,15,T7,
  220.              6, 6,15,T7,
  221.              6, 5,15,T7,
  222.              6, 4,15,T7,
  223.              6, 3,15,T7,
  224.              6, 2,15,T7,
  225.              6, 1,15,T7,
  226.              1, 0,128,0,
  227.  
  228.              -1,            /* No8 仮死ボス命中音 */
  229.              7, 8,17,T8,
  230.              7, 1,17,T8,
  231.              7,10,17,T8,
  232.              7,12,17,T8,
  233.              1, 0,128,0,
  234.  
  235.              -1,            /* No9 人追加音 */
  236.              5, 1,11,T9,
  237.              5, 5,11,T9,
  238.              5, 8,11,T9,
  239.              5, 1,11,T9,
  240.              5, 5,11,T9,
  241.              5, 8,11,T9,
  242.              5, 1,11,T9,
  243.              5, 5,11,T9,
  244.              5, 8,11,T9,
  245.              1, 0,128,0,
  246.  
  247.              -1,            /* No10 ボス目覚め音 */
  248.              3, 1,11,T10,
  249.              3, 2,11,T10,
  250.              3, 3,11,T10,
  251.              3, 4,11,T10,
  252.              3, 5,11,T10,
  253.              3, 6,11,T10,
  254.              3, 7,11,T10,
  255.              3, 8,11,T10,
  256.              3, 9,11,T10,
  257.              3,10,11,T10,
  258.              3,11,11,T10,
  259.              3,12,11,T10,
  260.              4, 1,11,T10,
  261.              4, 2,11,T10,
  262.              4, 3,11,T10,
  263.              4, 4,11,T10,
  264.              4, 5,11,T10,
  265.              4, 6,11,T10,
  266.              4, 7,11,T10,
  267.              4, 8,11,T10,
  268.              4, 9,11,T10,
  269.              4,10,11,T10,
  270.              4,11,11,T10,
  271.              4,12,11,T10,
  272.              5, 1,11,T10,
  273.              5, 2,11,T10,
  274.              5, 3,11,T10,
  275.              5, 4,11,T10,
  276.              5, 5,11,T10,
  277.              5, 6,11,T10,
  278.              5, 7,11,T10,
  279.              5, 8,11,T10,
  280.              5, 9,11,T10,
  281.              5,10,11,T10,
  282.              5,11,11,T10,
  283.              5,12,11,T10,
  284.              1, 0,128,0,
  285.  
  286.              -1,            /* No11 リミット減少音 */
  287.              5,10,11,T11,
  288.              5,10,12,T11,
  289.              5,10,13,T11,
  290.              5,10,14,T11,
  291.              5,10,15,T11,
  292.              5,10,16,T11,
  293.              5,10,17,T11,
  294.              5,10,18,T11,
  295.              5,10,19,T11,
  296.              5,10,20,T11,
  297.              5,10,22,T11,
  298.              5,10,24,T11,
  299.              5,10,26,T11,
  300.              5,10,28,T11,
  301.              5,10,30,T11,
  302.              5,10,34,T11,
  303.              5,10,38,T11,
  304.              1, 0,128,0,
  305.  
  306.              -1,
  307.              -2
  308.             };
  309.  
  310.  
  311.  
  312. main()
  313. {
  314.  int i,j;
  315.  int dx,dy;
  316.  
  317.  end=0; /* ゲーム終了フラグ */
  318.  
  319.  if (load_chr()==0) return 0; /* キャラクタパターンデータのバイナリ形式load */
  320.  make_chr();                  /* キャラクタパターンデータの8×8分割 */
  321.  for (i=0;i<64;i++) chr[8][i]=1; /* 空白パターン作成 */
  322.  hi_score=0;
  323.  
  324.  g_init(gwork);                 /* グラフィック画面の初期化 */
  325.  sprite(1);                     /* スプライト表示開始 */
  326.  SPR_display(1,120);            /* スプライトの表示個数 */
  327.  
  328.  binit(); /* サウンド処理初期化 */
  329.  
  330.  if (load_sprite()==0) return 0; /* スプライトパターンのバイナリ形式read */
  331.  
  332. while(1) /* メインループ */
  333.  {
  334.   demo(); /* デモ */
  335.   if (end==1) break; /* ゲーム終了 */
  336.   title(0); /* タイトル表示 */
  337.  
  338.   game_over=0;
  339.   life=5;  /* 人の残り */
  340.   gain=0;  /* 人追加フラグ */
  341.   max_alien=2;
  342.   score=0;
  343.   while(game_over==0) /* 1ゲームループ */
  344.    {
  345.     dot=389; /* ドットの残り */
  346.     map(0);   /* フィールドの作成 */
  347.     init(0);  /* 1面初期化 */
  348.     while( (clear==0) && (game_over==0) ) /* 1面ループ */
  349.      {
  350.       alien(); /* エイリアンの移動 */
  351.       spk++; if (spk>SPK) {move(); timer(); spk=0;}; /* 人の移動 */
  352.       spb++; if (spb>SPB) {arrow(); spb=0;}; /* 矢の移動 */
  353.       if ((INPB(0x04d0) & 0x03)==0) game_over=1; /* SELECTボタン -> 強制終了 */
  354.       if ((INPB(0x04d0) & 0x0c)==0) /* RUNボタン -> PAUSE */
  355.        {
  356.         fm_init(); /* 音の停止 */
  357.         while((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  358.         dx=108; dy=240;
  359.         EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx,dy,"PAUSE");
  360.         while((INPB(0x04d0) & 0x0c)!=0);    /* RUNボタンを押すまで待つ */
  361.         for (j=0;j<16;j++) {for (i=0;i<40;i++) g_pset(g_loc(dx+i,dy-j),0);};
  362.         EGB_color(gwork,0,0x7fff);
  363.         while((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  364.        };
  365.       bgm(); /* サウンド処理 */
  366.       wait();
  367.       for (i=0;i<max_alien;i++) /* エイリアンと人の接触判定 */
  368.        {if ((aj[i]>0)&&(abs(ax[i]-kx)<6)&&(abs(ay[i]-ky)<6)) dead();};
  369.       if ( (gain==0) && (score>=800) ) /* 人を追加 */
  370.        {gain=1; life++; pr_life();
  371.         spoint[4]=sinit[9]; skunt[4]=0;}; /* 人追加音 */
  372.      };
  373.     fm_init(); for (i=0;i<6;i++) spoint[i]=0; /* 音の停止 */
  374.     for (i=0;i<1000;i++) wait();/* 面クリア後の余韻 */
  375.     max_alien++; if (max_alien>=8) max_alien=3;
  376.    };
  377.   /* ゲームオーバー処理 */
  378.   for (i=0;i<60;i++) sp_dsp(i,0);
  379.   dx=X+52; dy=Y+104;
  380.   EGB_color(gwork,0,1); EGB_putSjis(gwork,dx+2,dy+2,"GAME OVER");
  381.  EGB_color(gwork,0,(R+G)*31);EGB_putSjis(gwork,dx+1,dy+1,"GAME OVER");
  382.   EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx,dy,"GAME OVER");
  383.   if (score>hi_score) /* ハイスコア取得 */
  384.    {
  385.     hi_score=score; pr_score(1);
  386.     EGB_color(gwork,0,1);
  387.     EGB_putSjis(gwork,dx+4+1,dy+48+1,"You Get Hi-SCORE.");
  388.     EGB_color(gwork,0,(R+G)*31);
  389.     EGB_putSjis(gwork,dx+4,dy+48,"You Get Hi-SCORE.");
  390.    };
  391.   EGB_color(gwork,0,1); EGB_putSjis(gwork,dx+12+1,dy+100+1,"Push A button");
  392.   EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+12,dy+100,"Push A button");
  393.   while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  394.   while ((INPB(0x04d0) & 0x10)==0x10); /* Aボタンを押すまで待つ */
  395.  };
  396.  
  397.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  398.  
  399.  
  400.  fm_init(); /* FM音源の停止 */
  401.  g_cls();
  402.  sprite(0); /* スプライト表示停止 */
  403.  
  404.  screenterm( gwork ) ;  /* MS-DOSの画面モード */
  405.  
  406. };
  407.  
  408.  
  409.  
  410. title(mode)
  411.         /* タイトル表示 */
  412.  int mode;     /* 0:本番用 1:デモ用 */
  413. {
  414.  int dx,dy;
  415.  
  416.  EGB_fontStyle(gwork,1); /* 太文字 */
  417.  EGB_textZoom(gwork,0,8,16); /* ANKの拡大率 */
  418.  dx=252; dy=24;
  419.  EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+2,dy+2,"Atomic");
  420.  EGB_color(gwork,0,(R+G)*31); EGB_putSjis(gwork,dx+1,dy+1,"Atomic");
  421.  EGB_color(gwork,0,0x7fff); EGB_putSjis(gwork,dx,dy,"Atomic");
  422.  dy=dy+16;
  423.  EGB_color(gwork,0,R*31); EGB_putSjis(gwork,dx+2,dy+2,"   ALIEN");
  424.  EGB_color(gwork,0,(R+G)*31); EGB_putSjis(gwork,dx+1,dy+1,"   ALIEN");
  425.  EGB_color(gwork,0,0x7fff); EGB_putSjis(gwork,dx,dy,"   ALIEN");
  426.  EGB_color(gwork,0,0x7fff);
  427.  dy=dy+32; EGB_putSjis(gwork,dx,dy,"Hi-SCORE");
  428.  if (mode!=1)
  429.    {          /* 本番用インフォーメーション */
  430.     dy=dy+40; EGB_putSjis(gwork,dx,dy,"SCORE");
  431.     dy=dy+40; EGB_putSjis(gwork,dx,dy,"Life");
  432.     dy=dy+40; EGB_putSjis(gwork,dx,dy,"Limit");
  433.     dy=dy+20; EGB_putSjis(gwork,dx,dy," Boss");
  434.    }
  435.   else
  436.    {          /* デモ用インフォーメーション */
  437.     EGB_color(gwork,0,(R+G)*31);
  438.     dy=dy+48; EGB_putSjis(gwork,dx,dy,   "Abutton");
  439.               EGB_putSjis(gwork,dx,dy+18,"→ START");
  440.     EGB_color(gwork,0,(B+G)*31);
  441.     dy=dy+40; EGB_putSjis(gwork,dx,dy,   "Bbutton");
  442.               EGB_putSjis(gwork,dx,dy+18,"→ About");
  443.     EGB_color(gwork,0,R*31);
  444.     dy=dy+40; EGB_putSjis(gwork,dx,dy,   "SELECT");
  445.               EGB_putSjis(gwork,dx,dy+18,"→ Exit");
  446.     EGB_color(gwork,0,0x7fff);
  447.    };
  448.  
  449. };
  450.  
  451.  
  452. demo()
  453.             /* デモ */
  454. {
  455.  int i;
  456.  
  457.  g_cls();
  458.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  459.  
  460.  title(1); /* タイトル表示 */
  461.  life=score=0; max_alien=8; dot=389;
  462.  map(1);  /* フィールドの作成(デモ用) */
  463.  init(1); /* 1面初期化(デモ用) */
  464.  
  465.  while (1) /* デモループ */
  466.   {
  467.    alien(); /* エイリアンの移動 */
  468.    wait();
  469.    i=INPB(0x04d0);
  470.    if ( (i & 0x10)==0 ) break;           /* Aボタン */
  471.    if ( (i & 0x20)==0 ) teach();         /* Bボタン */
  472.    if ( (i & 0x03)==0 ) {end=1; break;}; /* SELECTボタン */
  473.   };
  474.  for (i=0;i<60;i++) sp_dsp(i,0);
  475.  g_cls();
  476.  
  477. };
  478.  
  479.  
  480. short pat[8][8]; /* スプライトから作成したグラフィックパターン格納領域 */
  481.  
  482. teach()
  483.             /* 説明表示 */
  484. {
  485.  int i,x,y;
  486.  
  487.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  488.  for (i=0;i<60;i++) sp_dsp(i,0);
  489.  g_cls();
  490.  
  491.  EGB_color(gwork,0,0x7fff);
  492.  x=16; y=24; EGB_putSjis(gwork,160-16,y,"説明");
  493.  
  494.  y=y+20; sp_gr(0,0); g_put8(g_loc(x,y-12),pat);
  495.  EGB_putSjis(gwork,x+10,y,"を操作して、フィールド内のエイリアン");
  496.  EGB_putSjis(gwork,x,y+16,"を全て抹殺せよ");
  497.  
  498.  y=y+40; g_put8(g_loc(x,y-12),chr[7]);
  499.  EGB_putSjis(gwork,x+10,y,"が残っている間は、エイリアンを撃っても");
  500.  EGB_putSjis(gwork,x,y+16,"死なずにワープする");
  501.  
  502.  y=y+40; g_put8(g_loc(x,y-12),chr[7]);
  503.  EGB_putSjis(gwork,x+10,y,"がなくなってから、  を撃つと、しばらく");
  504.  sp_gr(12,0); g_put8(g_loc(x+16*8+12+10,y-12),pat);
  505.  EGB_putSjis(gwork,x,y+16,"の間は仮死状態(  )になる");
  506.  sp_gr(14,0); g_put8(g_loc(x+16*7+12,y+16-12),pat);
  507.  
  508.  y=y+40; EGB_putSjis(gwork,x,y,"その間に  を撃つと死亡する");
  509.  sp_gr(10,0); g_put8(g_loc(x+16*4+4,y-12),pat);
  510.  
  511.  y=y+22; sp_gr(10,0); g_put8(g_loc(x,y-12),pat);
  512.  EGB_putSjis(gwork,x+10,y,"が全滅してから、  に3発命中させれば");
  513.  sp_gr(12,0); g_put8(g_loc(x+16*7+12+10,y-12),pat);
  514.  EGB_putSjis(gwork,x,y+16,"ラウンドクリア");
  515.  
  516.  EGB_putSjis(gwork,88,232,"Push  A button");
  517.  
  518.  
  519.  while ((INPB(0x04d0) & 0x10)==0x10); /* Aボタンを押すまで待つ */
  520.  g_cls();
  521.  while ((INPB(0x04d0) & 0x3f)!=0x3f); /* パッドを放すまで待つ */
  522.  
  523. /* 画面を元に戻す */
  524.  title(1); /* タイトル表示 */
  525.  map(1);  /* フィールドの作成(デモ用) */
  526.  init(1); /* 1面初期化(デモ用) */
  527.  
  528. };
  529.  
  530.  
  531. dead()
  532.           /* 人の死亡 */
  533. {
  534.  int i,j,k,add,f;
  535.  
  536. /* 死亡デモ */
  537.  spoint[0]=sinit[2]; skunt[0]=0; /* 人死亡音 */
  538.  for (j=0;(sdata[spoint[0]]!=-1);j++)
  539.   {sp_pat(0,15+((j>>4) & 1)); bgm(); wait();};
  540.  for (i=0;i<60;i++) sp_dsp(i,0); /* スプライト消去 */
  541.  fm_init(); for (i=0;i<6;i++) spoint[i]=0; /* 音の停止 */
  542.  life--; if (life==0) {game_over=1; pr_life(); return 0;};
  543.  
  544.  for (i=0;i<500;i++) wait(); /* ウェイト */
  545.  init(0);
  546.  if (dot==0) /* ドットがない状態ならドットを1つ配置する */
  547.   {
  548.    while(1) {i=rnd(26)+2; j=rnd(22)+2;
  549.              for (k=f=0;k<8;k++) /* エイリアンに重なるか */
  550.               {if ( (aj[k]==1) && ((ax[k]/8)==i) && ((ay[k]/8)==j) ) f=1;};
  551.              if (f==1) continue; /* 重なった */
  552.              if (MAP[j][i]==8) {MAP[j][i]=7; break;};};
  553.    dot=1; add=g_loc(i*8+X,j*8+Y);
  554.    spoint[5]=sinit[10]; skunt[5]=0; /* ボス目覚め音(代用) */
  555.    for (k=0;(sdata[spoint[5]]!=-1);k++) /* ドット配置デモ */
  556.     {if ( (k%16)<7 ) g_put8(add,chr[7]); else g_put8(add,chr[8]);
  557.      bgm(); wait(); wait();};
  558.    g_put8(add,chr[7]); /* ドットの表示 */
  559.    for (i=0;i<700;i++) wait(); /* ウェイト */
  560.   };
  561.  
  562. };
  563.  
  564.  
  565. init(mode)
  566.                /* 変数の初期化 */
  567.  int mode;     /* 0:本番用(ワープ音あり) 1:デモ用(ワープ音なし) */
  568. {
  569.  int i,j,f;
  570.  
  571.  
  572.  pr_score(1); /* ハイスコア表示 */
  573.  
  574. if (mode!=1) /* 本番時のみインフォーメーション表示 */
  575.  {
  576.   pr_score(0); /* スコア表示 */
  577.   pr_life(); /* 残り人数表示 */
  578.   left_alien=max_alien; /* エイリアンの数 */
  579.   limit=dumm_boss=0; /* ボスエイリアンのダメージ */
  580.   information(); /* 制限時間の表示 */
  581.   clear=0; /* ステージクリアフラグ */
  582.  };
  583.  
  584.  spk=0;      /* 人のスピードワーク */
  585.  kx=(31-2)*8+X+1; ky=(27-3)*8+Y; kh=2; /* 人変数の初期化 */
  586.  if (mode!=1) /* デモでなければ人を表示 */
  587.   {sp_init(0,kx+X,ky+Y,0,kh,0); sp_dsp(0,1);}; /* 人のスプライトの初期化 */
  588.  
  589.  bj=0;      /* 矢の状態  0:発射可能 1:飛行中 2:発射準備 */
  590.  spb=0;     /* 矢のスピードワーク */
  591.  sp_init(1,bx,by,0,0,0); sp_dsp(1,0); /* 矢のスプライトの初期化 */
  592.  
  593.  for (i=0;i<8;i++) {aj[i]=spa[i]=0; SPA[i]=SPA00;}; /* エイリアンの初期設定 */
  594.  for (i=0;i<max_alien;i++)
  595.   {
  596.    if (i==0) {SPA[0]=SPA00; j=12;} /* ボスのスピード初期値とキャラクタNo */
  597.     else     {SPA[i]=SPA10; j=8;}; /* ザコのスピード初期値とキャラクタNo */
  598.    aj[i]=1; spa[i]=i; warp(i); /* 座標等 */
  599.    sp_init(i+2,ax[i]+X,ay[i]+Y,0,j,0);
  600.    sp_dsp(i+2,1); /* alienのスプライトの初期化 */
  601.    if (mode!=1) {spoint[0]=sinit[1]; skunt[0]=0; warp(-1);}; /* ワープ音 */
  602.   };
  603.  if (mode!=1) {for (i=0;i<700;i++) wait();}; /* ウェイト */
  604.  
  605. };
  606.  
  607.  
  608. map(mode)
  609.           /* フィールドの作成 */
  610.  int mode;  /* 0:本番用マップ作成 1:デモ用マップ作成 */
  611. {
  612.  int i,j;
  613.  int mx=31,my=27;
  614.  
  615.  if (mode==1) /* デモならテロップ表示 */
  616.   {EGB_color(gwork,0,R*31); EGB_putSjis(gwork,96,240,"DEMO");};
  617.  
  618.  /* 本番ならdotで、デモなら空白で通路をうめる */
  619.  for (j=0;j<my;j++) {for (i=0;i<mx;i++) MAP[j][i]=7+mode;};
  620.  
  621.  for (j=0;j<my;j++) MAP[j][0]=MAP[j][mx-1]=6; /* 縦枠 */
  622.  for (i=0;i<mx;i++) MAP[0][i]=MAP[my-1][i]=6; /* 横枠 */
  623.  
  624.  for (j=2;j<(my-3);j=j+3) /* コーナー */
  625.   {
  626.    for (i=2;i<(mx-4);i=i+4)
  627.     {
  628.      MAP[j][i]=0; MAP[j][i+1]=4; MAP[j][i+2]=1;
  629.      MAP[j+1][i]=2; MAP[j+1][i+1]=5; MAP[j+1][i+2]=3;
  630.     };
  631.   };
  632.  
  633.  for (j=0;j<my;j++) /* マップ表示 */
  634.   {for (i=0;i<mx;i++) g_put8(g_loc(i*8+X,j*8+Y),chr[MAP[j][i]]);};
  635.  
  636. };
  637.  
  638.  
  639. move()
  640.             /* 人の移動 */
  641. {
  642.  int p,i;
  643.  
  644.  p=INPB(0x04d0);
  645.  
  646. /* 現在と反対方向へは随時方向転換可能 */
  647.  if ( ((p & 0x01)==0) && (kh==1) ) kh=0; /* 上 */
  648.  if ( ((p & 0x02)==0) && (kh==0) ) kh=1; /* 下 */
  649.  if ( ((p & 0x04)==0) && (kh==3) ) kh=2; /* 左 */
  650.  if ( ((p & 0x08)==0) && (kh==2) ) kh=3; /* 右 */
  651.  
  652.  /* それ以外の方向は8×8の枠内なら方向転換可能 */
  653.  if ( ((kx%8)==0) && ((ky%8)==0) )
  654.   { /* 変更後の方向に進めれば方向を変更 */
  655.    if ( ((p & 0x01)==0) && (MAP[(ky-1)/8][kx/8]>WALL) ) kh=0; /* 上 */
  656.    if ( ((p & 0x02)==0) && (MAP[(ky+8)/8][kx/8]>WALL) ) kh=1; /* 下 */
  657.    if ( ((p & 0x04)==0) && (MAP[ky/8][(kx-1)/8]>WALL) ) kh=2; /* 左 */
  658.    if ( ((p & 0x08)==0) && (MAP[ky/8][(kx+8)/8]>WALL) ) kh=3; /* 右 */
  659.   };
  660.  
  661.  switch(kh)
  662.   { /* 進んだ先が障害物でなければ移動 */
  663.    case 0: if (MAP[(ky-1)/8][kx/8]>WALL) ky--; break; /* 上 */
  664.    case 1: if (MAP[(ky+8)/8][kx/8]>WALL) ky++; break; /* 下 */
  665.    case 2: if (MAP[ky/8][(kx-1)/8]>WALL) kx--; break; /* 左 */
  666.    case 3: if (MAP[ky/8][(kx+8)/8]>WALL) kx++; break; /* 右 */
  667.   };
  668.  
  669.  /* dot処理 */
  670.  if ( (MAP[ky/8][kx/8]==7) &&  ((kx%8)==0) && ((ky%8)==0) )
  671.   {
  672.    MAP[ky/8][kx/8]=8; g_put8(g_loc(kx/8*8+X,ky/8*8+Y),chr[8]);
  673.    dot--; /* ドットの残り */
  674.    score++; pr_score(0); /* スコア表示 */
  675.    spoint[1]=sinit[0]; skunt[1]=0; /* ドット喰い音 */
  676.    if (dot==0) {for (i=1;i<8;i++) SPA[i]=SPA11;}; /* ドット0=>ザコのスピードアップ */
  677.   };
  678.  
  679.  sp_pat(0,kh); sp_move(0,kx+X,ky+Y); /* 人の表示 */
  680.  
  681.  
  682.  if ((p & 0x10)==0) /* Aボタン */
  683.        {if (bj==0) {bj=1; bh=kh; bx=kx; by=ky; /* 矢を発射 */
  684.                     spoint[2]=sinit[7]; skunt[2]=0; /* アロー発射音 */
  685.                     sp_init(1,bx+X,by+Y,0,bh+4,0); sp_dsp(1,1);};}
  686.   else {if (bj==2)  bj=0;}; /* 矢の発射準備 */
  687.  
  688. };
  689.  
  690.  
  691. arrow()
  692.             /* 矢の移動 */
  693. {
  694.  int f=0; /* 消滅フラグ 0:飛行続行 1:飛行中断 */
  695.  int i;
  696.  
  697.  if (bj!=1) return 0; /* 矢が飛行していない */
  698.  
  699.  switch(bh)
  700.   { /* 移動(進んだ先が障害物なら飛行中断) */
  701.    case 0: if (MAP[(by-1)/8][bx/8]>WALL) by--; else f=1; /* 上 */
  702.            break;
  703.    case 1: if (MAP[(by+8)/8][bx/8]>WALL) by++; else f=1; /* 下 */
  704.            break;
  705.    case 2: if (MAP[by/8][(bx-1)/8]>WALL) bx--; else f=1; /* 左 */
  706.            break;
  707.    case 3: if (MAP[by/8][(bx+8)/8]>WALL) bx++; else f=1; /* 右 */
  708.            break;
  709.   };
  710.  
  711.  for (i=0;i<8;i++) /* エイリアンとの命中判定 */
  712.   {
  713.    if ( (abs(bx-ax[i])<7) && (abs(by-ay[i])<7) && (aj[i]!=0) )
  714.     {
  715.      f=1; sp_dsp(1,0); /* 矢を消す */
  716.      if (dot==0) /* ドットが無い */
  717.        {
  718.         if (i==0) /* ボス */
  719.           {
  720.            if (aj[0]==2)  /* ボスが仮死状態なら矢は消滅 */
  721.             {spoint[3]=sinit[8]; skunt[3]=0; break;}; /* 仮死ボス命中音 */
  722.            if (left_alien==1) /* 全てのザコが死亡 */
  723.              {
  724.               dumm_boss++; /* ボスエイリアンのダメージ増加 */
  725.               score=score+10;
  726.               information(); /* 制限時間とダメージの表示 */
  727.               if (dumm_boss>=3)
  728.                 {
  729.                  aj[i]=0; sp_dsp(i+2,0); /* 死亡 */
  730.                  score=score+20; clear=1; /* 面クリア */
  731.                  spoint[0]=sinit[5]; skunt[0]=0; /* ボス死亡音 */
  732.                 }
  733.                else {spoint[0]=sinit[4]; skunt[0]=0;}; /* ボスダメージ音 */
  734.               warp(0); /* ワープ */
  735.               break;
  736.              }
  737.             else /* ザコが残っている */
  738.              {
  739.               sp_pat(2,14); aj[0]=2; limit=LIMIT; score=score+7; /* 仮死状態 */
  740.               spoint[0]=sinit[3]; skunt[0]=0; warp(-1); /* ボス仮死音 */
  741.               break;
  742.              };
  743.           }
  744.          else /* ザコ */
  745.           {
  746.            if (aj[0]==2) /* ボスが仮死状態 */
  747.              {aj[i]=0; sp_dsp(i+2,0); score=score+10; left_alien--; /* 死亡 */
  748.               spoint[0]=sinit[6]; skunt[0]=0; warp(-1);} /* ザコ死亡音 */
  749.             else {score=score+5; /* ボスが健在ならワープ */
  750.                   spoint[0]=sinit[1]; skunt[0]=0; warp(i);}; /* ワープ音 */
  751.            break;
  752.           };
  753.        }
  754.      else /* ドットが残っている */
  755.       {
  756.        spoint[0]=sinit[1]; skunt[0]=0; /* ワープ音 */
  757.        warp(i); /* ボスもザコもワープ */
  758.        score=score+5;
  759.        break;
  760.       };
  761.     };
  762.   };
  763.  
  764.  if (f==1) {sp_dsp(1,0); bj=2; pr_score(0); /* スコア表示 */}; /* 飛行中断 */
  765.  
  766.  sp_move(1,bx+X,by+Y); /* 矢の表示 */
  767.  
  768. };
  769.  
  770.  
  771. warp(no)
  772.           /* エイリアンのワープ */
  773.  int no;  /* エイリアンの番号 */
  774. {
  775.  int f; /* ワープ先座標採用フラグ 0:採用 1:不採用 */
  776.  int i,x,y;
  777.  
  778.  if (no==-1) goto sound; /* 音出しのみ */
  779.  
  780.  x=(ax[no]/8)*8; y=(ay[no]/8)*8; /* ワープ前の位置保存 */
  781.  while(1)
  782.   {
  783.    f=0; ax[no]=(rnd(28)+1)*8; ay[no]=(rnd(24)+1)*8;
  784.    if ( (abs(ax[no]-x)<16) && (abs(ay[no]-y)<16) ) f=1; /* 元の位置に重なる */
  785.    if ( (abs(ax[no]-kx)<16) && (abs(ay[no]-ky)<16) ) f=1; /* 人に重なる */
  786.    for (i=0;i<8;i++) /* 他のエイリアンに重なる */
  787.     {if ( (no!=i) && (aj[i]==1)
  788.        && (abs(ax[no]-ax[i])<8) && (abs(ay[no]-ay[i])<8) ) f=1;};
  789.    if (MAP[ay[no]/8][ax[no]/8]<=WALL) f=1; /* 障害物に重なる */
  790.    if (f==0) break; /* 座標が採用された */
  791.   };
  792.  
  793.  while(1) /* 乱数による方向決定 */
  794.   {
  795.    ah[no]=rnd(3);
  796.    if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) break; /* 上*/
  797.    if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) break; /* 下*/
  798.    if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) break; /* 左*/
  799.    if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) break; /* 右*/
  800.   };
  801.  
  802.  sp_move(no+2,ax[no]+X,ay[no]+Y); /* エイリアンの表示 */
  803.  
  804.  sound: /* 音出し兼ウェイト */
  805.   while(sdata[spoint[0]]!=-1) {bgm(); for (i=0;i<2;i++) wait();};
  806.  
  807. };
  808.  
  809.  
  810. timer()
  811.           /* ボスエイリアンの目覚め時間 */
  812. {
  813.  int i;
  814.  int wlimit;
  815.  
  816.  if (limit==0) return 0;
  817.  
  818.  wlimit=limit/100; limit--;
  819.  if (wlimit!=limit/100) {information(); /* 制限時間の表示 */
  820.                          spoint[1]=sinit[11]; skunt[1]=0;}; /* リミット減少音*/
  821.  
  822.  if (left_alien==1) /* ザコ全滅ならボスを即復活 & スピードアップ */
  823.   {limit=0; information(); SPA[0]=SPA01;};
  824.  
  825.  if (limit<=0)
  826.   {
  827.    aj[0]=1; dumm_boss=0; /* ボスエイリアンのダメージ復活 */
  828.    spoint[5]=sinit[10]; skunt[5]=0; /* ボス目覚め音 */
  829.    for (i=0;(sdata[spoint[5]]!=-1);i++) /* 目覚めデモ */
  830.     {if ( (i%16)<7 ) sp_pat(2,12); else sp_pat(2,14);
  831.      bgm(); wait(); wait();};
  832.   };
  833.  
  834.  
  835. };
  836.  
  837.  
  838. information()
  839.               /* 制限時間の表示 */
  840. {
  841.  int x,y;
  842.  int add;
  843.  int wlimit;
  844.  
  845.  /* 制限時間の表示 */
  846.  x=296; y=176; add=g_loc(x,y);
  847.  wlimit=limit;
  848.  g_put(add,num[wlimit/1000]); wlimit=wlimit%1000;
  849.  g_put(add+20,num[wlimit/100]);
  850.  
  851.  /* ボスのダメージの表示 */
  852.  x=x+8; y=y+20; add=g_loc(x,y); g_put(add,num[3-dumm_boss]);
  853.  
  854. };
  855.  
  856.  
  857. pr_score(mode)
  858.               /* スコアの表示 */
  859.  int mode;    /* 0:スコア表示 1:ハイスコア表示 */
  860. {
  861.  int x,y;
  862.  int add;
  863.  int wscore;
  864.  
  865.  switch(mode)
  866.   {
  867.    case 0 : x=256; y=112; wscore=score; break;
  868.    case 1 : x=256; y=72; wscore=hi_score; break;
  869.   };
  870.  add=g_loc(x,y+1);
  871.  
  872.  g_put(add,num[wscore/10000]); wscore=wscore%10000;
  873.  g_put(add+20,num[wscore/1000]); wscore=wscore%1000;
  874.  g_put(add+40,num[wscore/100]); wscore=wscore%100;
  875.  g_put(add+60,num[wscore/10]);
  876.  g_put(add+80,num[wscore%10]);
  877.  g_put(add+100,num[0]);
  878.  
  879. };
  880.  
  881.  
  882.  pr_life()
  883.            /* 残り人数表示 */
  884. {
  885.  int i;
  886.  int x,y,add;
  887.  short blank[64];
  888.  
  889.  x=256; y=136; g_put(g_loc(x+36,y),num[life]);
  890.  
  891.  sp_gr(0,0); /* 残り表示用グラフィックパターンの作成 */
  892.  for (i=0;i<64;i++) blank[i]=0;
  893.  
  894.  add=g_loc(x,y+16+1);
  895.  for (i=0;i<5;i++) g_put8(add+18*i,blank); /* 残り表示領域の消去 */
  896.  if (life<1) return 0; /* 残り表示は数値のみで良い */
  897.  for (i=0;i<5;i++) if ((life-1)>i) g_put8(add+18*(4-i),pat); /* 残り表示 */
  898.  
  899. };
  900.  
  901.  
  902. sp_gr(no,pal)
  903.                 /* スプライトパターンからグラフィックパターン(8×8)を作成 */
  904.  int no;  /* スプライトパターン番号 */
  905.  int pal; /* カラーパレット番号 */
  906. {
  907.  int x,y;
  908.  
  909.  for (y=0;y<8;y++)
  910.   {
  911.    for (x=0;x<8;x++) pat[y][x]=sp_point(no,x,y,pal);
  912.   };
  913.  
  914. };
  915.  
  916.  
  917. alien()
  918.             /* エイリアンの移動 */
  919. {
  920.  int no;
  921.  int i;
  922.  int wah;
  923.  int s; /* 方向転換フラグ(ワーク) 0:方向転換可能 1:方向転換不可 */
  924.  
  925.  for (no=0;no<8;no++)
  926.   {
  927.    spa[no]++; if (spa[no]<SPA[no]) continue; spa[no]=0; /* タイマー */
  928.    if (aj[no]==0) {for (i=0;i<100;i++); continue;}; /* 死亡エイリアンをとばす*/
  929.  
  930.    wah=(ah[no]&2)+((ah[no]+1)&1); /* 現在の方向の反対方向 */
  931.    if ( ((ax[no]%(4*8))==(8*1)) && ((ay[no]%(3*8))==(8*1)) ) /* 交差点 */
  932.     {
  933.      s=0;
  934.      if (rnd(1)==0) /* 現在の方向に進めれば1/2の確率で方向を維持 */
  935.       {
  936.        if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1; /* 上 */
  937.        if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1; /* 下 */
  938.        if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1; /* 左 */
  939.        if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1; /* 右 */
  940.       }
  941.      if (rnd(9)==1) /* 1/10確率で追跡するかを決定 */
  942.        { /* 追跡 */
  943.         while(s==0)
  944.          {
  945.           if ( (abs(ax[no]-kx)<8) && (abs(ay[no]-ky)<8) )
  946.            {ah[no]=(ah[no]&2)+((ah[no]+1)&1); break;};/*無限ループ防止(テスト用)*/
  947.           if (rnd(1)==0) /* 1/2の確率でX,Y方向の優先度を決定 */
  948.             {
  949.              if (ay[no]>ky) ah[no]=0;
  950.              if (ay[no]<ky) ah[no]=1;
  951.             }
  952.            else
  953.             {
  954.              if (ax[no]>kx) ah[no]=2;
  955.              if (ax[no]<kx) ah[no]=3;
  956.             };
  957.           if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1;/* 上 */
  958.           if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1;/* 下 */
  959.           if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1;/* 左 */
  960.           if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1;/* 右 */
  961.          };
  962.        }
  963.       else
  964.        { /* 乱数による方向変換 */
  965.         while(s==0)
  966.          {
  967.           ah[no]=rnd(3);
  968.           if (ah[no]==wah) continue; /* 現在と反対方向にはしない */
  969.           if ( (ah[no]==0) && (MAP[(ay[no]-1)/8][ax[no]/8]>WALL) ) s=1; /* 上*/
  970.           if ( (ah[no]==1) && (MAP[(ay[no]+8)/8][ax[no]/8]>WALL) ) s=1; /* 下*/
  971.           if ( (ah[no]==2) && (MAP[ay[no]/8][(ax[no]-1)/8]>WALL) ) s=1; /* 左*/
  972.           if ( (ah[no]==3) && (MAP[ay[no]/8][(ax[no]+8)/8]>WALL) ) s=1; /* 右*/
  973.          };
  974.        };
  975.     };
  976.  
  977.    for (i=0;i<8;i++) /* エイリアン同志の衝突判定 */
  978.     {
  979.      if ( (no!=i) && (aj[i]!=0) 
  980.        && (abs(ax[no]-ax[i])<6) && (abs(ay[no]-ay[i])<6) )
  981.       {ah[no]=wah; break;}; /* 元の方向の反対方向にする */
  982.     };
  983.  
  984.    if (aj[no]!=2) /* 仮死状態でない */
  985.     {
  986.      switch(ah[no]) /* 移動 */
  987.       {
  988.        case 0: ay[no]--; break; /* 上 */
  989.        case 1: ay[no]++; break; /* 下 */
  990.        case 2: ax[no]--; break; /* 左 */
  991.        case 3: ax[no]++; break; /* 右 */
  992.       };
  993.     };
  994.  
  995.  
  996.    if (no==0)
  997.      {              /* ボス */
  998.       if (aj[0]==1) sp_pat(2,12+(ax[0]+ay[0])%2); /* 生存 */
  999.        else         sp_pat(2,14);                 /* 仮死 */
  1000.      }
  1001.     else
  1002.      {              /* ザコ */
  1003.       if (dot>0)    sp_pat(no+2,8+(ax[no]+ay[no])%2);  /* ドットあり */
  1004.        else         sp_pat(no+2,10+(ax[no]+ay[no])%2); /* ドットなし */
  1005.      };
  1006.  
  1007.    sp_move(no+2,ax[no]+X,ay[no]+Y); /* エイリアンの表示 */
  1008.   };
  1009.  
  1010. };
  1011.  
  1012.  
  1013. wait()
  1014. {
  1015.  int i;
  1016.  
  1017.  for (i=0;i<300;i++);
  1018.  
  1019. };
  1020.  
  1021.  
  1022. g_put8(a,c)
  1023.                    /* 8X8dot put高速版(何の制御もなし) */
  1024.  int a;            /* VRAMアドレス */
  1025.  short c[];        /* キャラクタデータ先頭アドレス */
  1026.  
  1027. {
  1028.  asm("      pushl %ebx");
  1029.  asm("      pushl %edx");
  1030.  asm("      pushl %esi");
  1031.  asm("      pushl %edi");                  /* スタック +16 */
  1032.  
  1033.  asm("      movl  24(%esp),%eax");         /* VRAM アドレス */
  1034.  asm("      movl  28(%esp),%ebx");         /* キャラクタデータ アドレス */
  1035.  
  1036.  asm("      pushl %ds");
  1037.  
  1038.  asm("    pushl $0x0104");               /* VRAM セレクタ */
  1039.  asm("      popl  %ds");
  1040.  
  1041.  asm("      movl  $0,%esi");               /* VRAM X方向オフセット */
  1042.  asm("      movl  $0,%edi");               /* キャラクタデータオフセット */
  1043.  asm("lva:movl  %ss:(%ebx,%edi,4),%edx");/* キャラクタデータ(4バイト)をedxにロード */
  1044.  asm("    movl  %edx,(%eax,%esi,4)");    /* edxをVRAMにストア */
  1045.  asm("      incl  %edi");
  1046.  asm("      incl  %esi");
  1047.  asm("      cmpl  $4 , %esi");             /* 1行分のループ */
  1048.  asm("      jnz   lva");
  1049.  asm("      movl  $0,%esi");               /* VRAM X方向オフセットのクリア */
  1050.  asm("      addl  $0x400,%eax");           /* VRAMアドレスの更新 */
  1051.  asm("      cmpl  $32,%edi");              /* 4X8dot分のループ */
  1052.  asm("      jnz   lva");
  1053.  
  1054.  asm("       popl  %ds");
  1055.  
  1056.  asm("      popl  %edi");
  1057.  asm("      popl  %esi");
  1058.  asm("      popl  %edx");
  1059.  asm("      popl  %ebx");
  1060.  
  1061. };
  1062.  
  1063.  
  1064. load_chr()
  1065.            /* キャラクタパターンデータのバイナリ形式load */
  1066. {
  1067.  int i,j;
  1068.  unsigned int h,l,end_f;
  1069.  int no;
  1070.  FILE *fp;
  1071.  
  1072.  fp=fopen(CHRFILE,"rb"); if (fp==NULL) return 0;
  1073.  
  1074.  end_f=0;
  1075.  
  1076.  for (no=0;((no<13)&&(end_f==0));no++)
  1077.   {
  1078.    for (i=0;i<256;i++)
  1079.     {
  1080.      h=getc(fp); l=getc(fp); work[no][i]=h*0x100+l;
  1081.      if (feof(fp)!=0) {end_f=1; break;};
  1082.     };
  1083.   };
  1084.  fclose(fp);
  1085.  
  1086. /* アナログ数字パターンの作成 */
  1087.  for (i=0;i<10;i++) {for (j=0;j<256;j++) num[i][j]=work[i+3][j];};
  1088.  
  1089.  return 1;
  1090.  
  1091. };
  1092.  
  1093.  
  1094. make_chr()
  1095.            /* キャラクタパターンデータの8×8分割 */
  1096. {
  1097.  int no; /* パターンデータワークの数 */
  1098.  int i,j;
  1099.  
  1100.  for (no=0;no<2;no++)
  1101.   {
  1102.    for (j=0;j<8;j++)
  1103.     {
  1104.      for (i=0;i<8;i++)
  1105.       {
  1106.        chr[no*4+0][j*8+i]=work[no][(j+0)*16+(i+0)];
  1107.        chr[no*4+1][j*8+i]=work[no][(j+0)*16+(i+8)];
  1108.        chr[no*4+2][j*8+i]=work[no][(j+8)*16+(i+0)];
  1109.        chr[no*4+3][j*8+i]=work[no][(j+8)*16+(i+8)];
  1110.       };
  1111.     };
  1112.   };
  1113.  
  1114. };
  1115.  
  1116.  
  1117. load_sprite()
  1118.                    /* スプライトパターンのバイナリ形式read */
  1119. {
  1120.  unsigned int h,l;
  1121.  int no,i,end_f;
  1122.  short color[16],pat[64];
  1123.  
  1124.  FILE *fp;
  1125.  
  1126.  fp=fopen(SPRITE,"rb"); if (fp==NULL) return 0;
  1127.  
  1128. /* カラーパレットのread */
  1129.  for (i=0;i<16;i++) {h=getc(fp); l=getc(fp); color[i]=h*0x100+l;};
  1130.  sp_def_color(0,color);
  1131.  
  1132. /* パターンデータのread */
  1133.  end_f=0;
  1134.  for (no=0;((no<256)&&(end_f==0));no++)
  1135.   {
  1136.    for (i=0;i<64;i++)
  1137.     {
  1138.       h=getc(fp); l=getc(fp); pat[i]=h*0x100+l;
  1139.       if (feof(fp)!=0) {end_f=1; break;};
  1140.     };
  1141.    sp_def_pat(no,pat); /* スプライトパターンの設定 */
  1142.   };
  1143.  
  1144.  fclose(fp);
  1145.  
  1146.  return 1;
  1147.  
  1148. };
  1149.  
  1150.  
  1151. binit()
  1152.               /* BGM処理の初期化 */
  1153. {
  1154.  int i,j;
  1155.  
  1156.  for (i=j=0;sdata[i]!=-2;i++)
  1157.   {
  1158.    if (sdata[i]==-1) {sinit[j]=i+1; j++;}; /* サウンドデータ先頭位置の算出 */
  1159.   };
  1160.  
  1161.  for (i=0;i<6;i++) spoint[i]=0; /* サウンドデータポインタの初期化 */
  1162.  
  1163.  fm_init();
  1164.  
  1165. };
  1166.  
  1167.  
  1168. bgm()
  1169.               /* BGM処理 */
  1170. {
  1171.  int ch,oct,tone,vol;
  1172.  
  1173.  for (ch=0;ch<6;ch++)
  1174.   {
  1175.    if (sdata[spoint[ch]]>-1)  /* 休止状態でない */
  1176.     {
  1177.      skunt[ch]--;
  1178.      if (skunt[ch]<0)         /* 変音時期 */
  1179.       {
  1180.        oct=sdata[spoint[ch]]; spoint[ch]++;
  1181.        tone=sdata[spoint[ch]]; spoint[ch]++;
  1182.        vol=sdata[spoint[ch]]; spoint[ch]++;
  1183.        skunt[ch]=sdata[spoint[ch]]; spoint[ch]++;
  1184.        fm_sound(ch,oct,tone,vol,feed[ch]);
  1185.       };
  1186.     };
  1187.   };
  1188.  
  1189. };
  1190.